/*******************************************************************************
 * Copyright 2011 Alexandre Zglav and Morphiastic
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.morphiastic.analysis.analyzers;

import java.io.IOException;
import java.util.Map;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;

import com.morphiastic.analysis.AnalysisComponentDefinition;
import com.morphiastic.utils.EqualsUtil;

/**
 * see
 * http://www.elasticsearch.org/guide/reference/index-modules/analysis/pattern
 * -analyzer.html
 * 
 * An analyzer of type pattern that can flexibly separate text into terms via a
 * regular expression. Accepts the following settings:
 * 
 * The following are settings that can be set for a pattern analyzer type:
 * 
 * Setting Description lowercase Should terms be lowercased or not. Defaults to
 * true. pattern The regular expression pattern, defaults to \W+. flags The
 * regular expression flags. IMPORTANT: The regular expression should match the
 * token separators, not the tokens themselves.
 * 
 * Flags should be pipe-separated, eg "CASE_INSENSITIVE|COMMENTS". Check Java
 * Pattern API for more details about flags options.
 * 
 * @author Alex
 * 
 */
public class PatternAnalyzer extends ElasticAnalyzer{
	
	
	public static final String LOWERCASE_PARAM_KEY = "lowercase";
	public static final String PATTERN_PARAM_KEY = "pattern";
	public static final String FLAGS_PARAM_KEY = "flags";
	
	
	
	
	private Boolean lowercase;
	private String pattern;
	private Integer flags;
	
	
	
	public PatternAnalyzer(String defName) {
		this(null, defName);
	}

	public PatternAnalyzer(Map<String,String> params, String defName) {
		super(ElasticAnalyzerType.pattern, defName);
		
		if(params!=null){
			
			String lowerCaseStr = params.get(LOWERCASE_PARAM_KEY);
			if(lowerCaseStr!=null && !lowerCaseStr.isEmpty()){
				this.lowercase = Boolean.parseBoolean(lowerCaseStr);
			}
			
			String patternStr = params.get(PATTERN_PARAM_KEY);
			if(patternStr!=null && !patternStr.isEmpty()){
				this.pattern = patternStr;
			}
			
			String flagsStr = params.get(FLAGS_PARAM_KEY);
			if(flagsStr!=null && !flagsStr.isEmpty()){
				try {
					this.flags = Integer.parseInt(flagsStr);
				} catch (NumberFormatException e) {
					// TODO: handle exception
				}
			}
		}
	}
	
	
	@Override
	public boolean hasCustomParams() {
		 if(this.lowercase != null || this.pattern!=null || this.flags != null)return true;
		 return false;
	}

	
	@Override
	public XContentBuilder addToBuilder(XContentBuilder mappingBuilder) throws IOException {
		
		mappingBuilder.startObject(getDefName())
		.field("type", getElasticAnalyzerType().toString());
		
		//add custom params
		if(this.lowercase!=null){
			mappingBuilder.field(LOWERCASE_PARAM_KEY, this.lowercase.booleanValue());
		}
		
		if(this.pattern != null && !this.pattern.isEmpty()){
			mappingBuilder.field(PATTERN_PARAM_KEY, this.pattern);
		}
		
		if(this.flags != null){
			mappingBuilder.field(FLAGS_PARAM_KEY, this.flags.intValue());
		}
		
		return mappingBuilder;
	}
	

	
	@Override
	public void setParamsFromSettings(Settings analyzerSettings) {
	
		
		
		String lowerCaseSetting = analyzerSettings.get(LOWERCASE_PARAM_KEY);
		if(lowerCaseSetting!=null && !lowerCaseSetting.isEmpty()){
			this.lowercase = Boolean.parseBoolean(lowerCaseSetting);
		}
		
		String patternSetting = analyzerSettings.get(PATTERN_PARAM_KEY);
		if(patternSetting!=null && !patternSetting.isEmpty()){
			this.pattern = patternSetting;
		}
		
		String flagsSetting = analyzerSettings.get(FLAGS_PARAM_KEY);
		if(flagsSetting!=null && !flagsSetting.isEmpty()){
			try {
				this.flags = Integer.parseInt(flagsSetting);
			} catch (NumberFormatException e) {
				// TODO: handle exception
			}
		}
	}
	
	
	
	@Override
	public boolean areEquivalentDefinitions(AnalysisComponentDefinition otherAnalyzer){
		
		if(otherAnalyzer==null)return false;
		PatternAnalyzer otherPatternAnalyzer ;
		try {
			otherPatternAnalyzer = (PatternAnalyzer)otherAnalyzer;
		} catch (ClassCastException e) {
			return false;
		}
		
		
		return 
		EqualsUtil.areEqual(this.lowercase, otherPatternAnalyzer.lowercase)
		&&
		EqualsUtil.areEqual(this.pattern, otherPatternAnalyzer.pattern)
		&&
		EqualsUtil.areEqual(this.flags, otherPatternAnalyzer.flags)
		;
	}
		
	

}
